using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Character : MonoBehaviour
{
    [Header("Knockback Info")]
    [SerializeField] protected Vector2 knockBackDirection;
    [SerializeField] protected float knockBackDuration;
    [SerializeField] public bool isKnocked;
    [SerializeField] public int impactResistance;

    #region Collisiion Info    
    [Header("Collision Info")]
    public Transform attackCheck;
    public float attackCheckRadius;

    [SerializeField] protected Transform groundCheck;         //������
    [SerializeField] protected float groundCheckDistance;     //���������

    [SerializeField] protected Transform wallCheck;           //ǽ����
    [SerializeField] protected float wallCheckDistance;       //ǽ�������

    [SerializeField] protected LayerMask IfIsGround;          //ͼ���ж�
    #endregion

    //��ɫ�����������
    #region  Direction Info     ���������������
    public int facingDir { get; private set; } = 1;         //��ɫ����1 ��ʾ���ң� -1 ��ʾ����
    protected bool facingRight = true;            //��ɫ�Ƿ���

    public System.Action onFlipped;
    #endregion

    //���
    #region Compoents   �������
    public Animator anim { get; private set; }
    public Rigidbody2D rb { get; private set; }

    public CharacterFX fx { get; private set; }
    public CharacterStats stats { get; private set; }
    #endregion


    protected virtual void Awake()
    {

    }

    protected virtual void Start()
    {
        anim = GetComponentInChildren<Animator>();      //��ȡ�������
        fx = GetComponent<CharacterFX>();
        rb = GetComponent<Rigidbody2D>();               //��ȡ�������
        stats = GetComponent<CharacterStats>();
    }

    protected virtual void Update()
    {

    }

    //��ײ��ع���
    #region Collision Function      ����ײ��⣩
    //�����ߵ���ײ���
    public bool IsGroundDetected() => Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, IfIsGround);
    public bool IsWallDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, wallCheckDistance, IfIsGround);

    protected virtual void OnDrawGizmos()
    {
        Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));
        Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance, wallCheck.position.y));
        Gizmos.DrawWireSphere(attackCheck.position, attackCheckRadius);
    }
    #endregion

    //ת����غ���
    #region Flip Function       �����������
    //��ɫ����ת����
    public void Flip()
    {
        facingDir = facingDir * -1;
        facingRight = !facingRight;
        transform.Rotate(0, 180, 0);

        if (onFlipped != null)
            onFlipped();
    }

    //���ƽ�ɫ����ת����
    public void FlipController(float _x)
    {
        if (_x > 0 && !facingRight)
            Flip();
        else if (_x < 0 && facingRight)
            Flip();
    }
    #endregion

    //�ٶ���غ���
    #region Velocity Function   ���ٶ����ã�
    //���ø����ٶȵĺ���
    public virtual void SetZeroVelocity()
    {
        if(isKnocked)
            return; 

        rb.velocity = Vector2.zero;
    }

    public virtual void SetVelocity(float _xVelocity, float _yVelocity)
    {
        if (isKnocked)
            return;

        rb.velocity = new Vector2(_xVelocity, _yVelocity);
        FlipController(_xVelocity);
    }
    #endregion


    public virtual void DamageEffect()                //�ܻ�����
    {
        fx.StartCoroutine("FlashFX");
        StartCoroutine("HitKnockback");
    }

    protected virtual IEnumerator HitKnockback()        //���˺���
    {
        isKnocked = true;

        rb.velocity = new Vector2(knockBackDirection.x * -facingDir, knockBackDirection.y);

        yield return new WaitForSeconds(knockBackDuration);
        isKnocked = false;
    }

    public virtual void Die()
    {

    }
}
